<?php

namespace slinks\common\io;

/**
 * Collects classes that implement the given interface. 
 * 
 * @author Navid Mitchell
 *
 */
class InterfaceCollectingClassVisitor implements IClassVisitor {

    private $classes = array();
    private $classesByType = array();
    private $interfaceNames;

    /**
     * 
     * @param array $interfaceNames the names of the interfaces that should qualify for collection. 
     */
    function __construct(array $interfaceNames) {
        $this->interfaceNames = $interfaceNames;
    }

    /**
     * This is called by the ClassReader when it reaches a new Class or Interface in the filesytem.
     * @param string $info the \SplFileInfo for the file containing the class.
     * @param string $name the name of the class being visited 
     */
    public function visit(\SplFileInfo $info, $name) {

        try {
            $reflectionClass = new \ReflectionClass($name);

            foreach ($this->interfaceNames as $interfaceName) {
                if ($reflectionClass->implementsInterface($interfaceName)) {

                    $this->classes[] = $reflectionClass;

                    $this->classesByType[$interfaceName][] = $reflectionClass;
                }
            }
        } catch (Exception $e) {
            // TODO: Log exceptions somewhere. 
        }
    }

    /**
     * @return and array of \ReflectionClass objects for all classes that implement the desired interface.
     */
    public function getClasses() {
        return $this->classes;
    }

    /**
     * @return all classes for the given interface name. 
     */
    public function getClassesForInterface($interfaceName) {
        return $this->classesByType[$interfaceName];
    }

}